package com.example.demo01.Socket.Client;


import cn.hutool.core.util.HexUtil;
import cn.hutool.core.util.StrUtil;
import com.example.demo01.Utils.FactoryPacketInstruction;
import com.example.demo01.VO.BasePacketInstruction;
import com.example.demo01.VO.IPacketInstruction;
import com.example.demo01.VO.TelNo00;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;


@Slf4j
@Component
public class NettyClient {


    @Value("${client.port}")
    private int port;
    @Value("${client.host}")
    private String host;
    private SocketChannel channel;


    private EventLoopGroup loop = new NioEventLoopGroup();

    @Resource
    private FactoryPacketInstruction factoryPacketInstruction;


    public void send(String telNo,String message) {
        if(channel==null||!channel.isActive()){
            throw new IllegalStateException("和服务器还未未建立起有效连接！，" +
                    "请稍后再试！！");
        }
        //000644583030
        IPacketInstruction packetInstruction=factoryPacketInstruction.getPacketInstruction(telNo);

        if(packetInstruction!=null){

          BasePacketInstruction basePacketInstruction=(BasePacketInstruction) packetInstruction;

            byte[] body= StrUtil.bytes(telNo+message, StandardCharsets.UTF_8);
            basePacketInstruction.setBody(body);
        }
        //        TelNo00 telNo00=new TelNo00();
//        telNo00.setBytes(new byte[]{
//                0x00,0x06,0x44,0x58,0x30,0x31
//        });


        channel.writeAndFlush(packetInstruction);
    }

    public Bootstrap createBootstrap(Bootstrap bootstrap, EventLoopGroup eventLoop) {

        if(bootstrap!=null) {


            bootstrap.group(eventLoop)
                    .channel(NioSocketChannel.class)
                    .remoteAddress(host, port)
                    .option(ChannelOption.SO_KEEPALIVE, true)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .handler(new ClientHandlerInitilizer());
            bootstrap.connect().addListener((ChannelFutureListener) future1 -> {
                if (future1.isSuccess()) {
                    log.info("连接Netty服务端成功");
                    channel = (SocketChannel) future1.channel();
                  //  this.send("");
                } else {
                    log.info("连接失败进行断线重连");
                    future1.channel().eventLoop().schedule(() -> start(), 20, TimeUnit.SECONDS);
                }
            });
        }

        return bootstrap;


    }
        @PostConstruct
    public void start() {

        createBootstrap(new Bootstrap(),loop);

    }


    @PreDestroy
    public void close() throws InterruptedException {
        if(channel !=null){

            log.info("client "+channel.localAddress() +" close ");
            channel.close().sync();
        }
    }
}
